package com.aiwu

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.text.buildSpannedString
import androidx.core.text.color
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.OutOfQuotaPolicy
import androidx.work.WorkManager
import com.aiwu.library.AiwuSimulator
import com.aiwu.library.EntryAbsActivity
import com.aiwu.library.bean.CheatDataBean
import com.aiwu.library.interfaces.DeleteGameCallback
import com.aiwu.library.netWork.BaseBean
import com.aiwu.library.netWork.CheatCallback
import com.aiwu.library.util.DialogUtil
import com.aiwu.library.util.IOUtil
import com.aiwu.library.util.LogUtil
import com.aiwu.library.util.MarketGamePathUtil
import com.aiwu.library.util.OtherUtil
import com.aiwu.library.util.SDCardUtils
import com.aiwu.utils.CitraUtil
import com.aiwu.utils.GameIdUtil
import com.aiwu.utils.InitFileUtil
import com.aiwu.utils.PrefsHelper
import com.alibaba.fastjson.JSON
import com.lzy.okgo.model.Response
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.citra.citra_emu.CitraApplication
import org.citra.citra_emu.NativeLibrary
import org.citra.citra_emu.activities.EmulationActivity
import org.citra.citra_emu.features.settings.model.Settings
import org.citra.citra_emu.features.settings.utils.SettingsFile
import org.citra.citra_emu.model.Game
import org.citra.citra_emu.utils.CiaInstallWorker
import org.citra.citra_emu.utils.CitraDirectoryHelper
import org.citra.citra_emu.utils.DirectoryInitialization
import org.citra.citra_emu.utils.GameHelper
import org.citra.citra_emu.utils.PermissionsHandler
import org.citra.citra_emu.utils.SystemSaveGame
import java.io.File
import java.lang.ref.WeakReference
import java.util.regex.Pattern

class EntryActivity : EntryAbsActivity() {
    companion object {
        //展示用的目录
        private const val GAME_DIR_PATH_SHOW = "25game/emuGame/3DS"
        private var instance: WeakReference<EntryActivity>? = null
        fun getInstance() = instance?.get()

        fun onSelectedDirectory(
            uri: Uri,
            isEmulatorData: Boolean,
            ok: () -> Unit,
            no: () -> Unit,
            isOk: (Boolean) -> Boolean = {
                val uriStr = uri.toString()
                if (isEmulatorData) {
                    uriStr.equals(CitraUtil.getEmuRootDirSAFPath(true), true)
                } else {
                    uriStr.endsWith(CitraUtil.GAME_DIR_PATH_SHORT, true)
                }
            },
        ) {
            if (isOk.invoke(isEmulatorData)) {
                ok.invoke()
            } else {
                no.invoke()
            }
        }

        fun onSelectedDirectory(
            uri: Uri, context: Context, isEmulatorData: Boolean,
            confirmOnClickListener: View.OnClickListener?,
            cancelOnClickListener: View.OnClickListener?, ok: () -> Unit
        ) {
            val uriStr = uri.toString()
            val isOk = if (isEmulatorData) {
                uriStr.equals(CitraUtil.getEmuRootDirSAFPath(true), true)
            } else {
                uriStr.endsWith(CitraUtil.GAME_DIR_PATH_SHORT, true)
            }
            if (isOk) {
                ok.invoke()
            } else {
                showFolderExplainDialog(
                    context,
                    false,
                    isEmulatorData,
                    confirmOnClickListener,
                    cancelOnClickListener
                )
            }
        }

        /**
         * 显示文件夹说明弹窗
         * @param isFirst 是否第一次选择文件夹
         * @param isEmulatorData true:模拟器数据文件夹。false:游戏文件夹
         */
        fun showFolderExplainDialog(
            context: Context,
            isFirst: Boolean,
            isEmulatorData: Boolean,
            confirmOnClickListener: View.OnClickListener?,
            cancelOnClickListener: View.OnClickListener?,
            dirPath: String = if (isEmulatorData) {
                "主SD卡${CitraUtil.EMU_ROOT_DIR_NAME}"
            } else {
                GAME_DIR_PATH_SHOW
            },
        ) {
            DialogUtil.showTip(
                context,
                context.getString(R.string.emu_lib_permission_title),
                buildSpannedString {
                    append(
                        if (isFirst) {
                            if (isEmulatorData) {
                                "请选择模拟器根目录"
                            } else {
                                "请选择游戏目录"
                            }
                        } else {
                            "文件夹选择错误，请选择"
                        }
                    )
                    color(context.getColor(R.color.color_4987C6)) {
                        append("\"")
                        append(dirPath)
                        append("\"")
                    }
                    append(if (isFirst) "并授予访问权限才能继续操作。" else "文件夹。")
                },
                if (isFirst) "去授权" else "继续选择",
                confirmOnClickListener,
                if (isFirst) "退出" else context.getString(R.string.emu_lib_cancel),
                cancelOnClickListener,
                false
            )
        }
    }

    private val preferences by lazy {
        PreferenceManager.getDefaultSharedPreferences(this)
    }
    private val emulatorDataPicker =
        registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
            it?.let { uri ->
                onSelectedDirectory(uri, true, {
                    //路径正确
                    val takeFlags =
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
                    contentResolver.takePersistableUriPermission(uri, takeFlags)
                    CitraDirectoryHelper.initializeCitraDirectory(uri)
                    onGrantedPermission()
                }, {
                    showFolderExplainDialog(isFirst = false, isEmulatorData = true)
                })
            } ?: showFolderExplainDialog(isFirst = true, isEmulatorData = true)
        }

    private var lastGameDirUriStr: String? = null
    private val gameDirPicker =
        registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
            it?.let { uri ->
                onSelectedDirectory(uri, false, {
                    //路径正确
                    val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                    contentResolver.takePersistableUriPermission(uri, takeFlags)
                    PrefsHelper.instance.addGameDirectory(uri.toString(), false)
                    preferences.edit()
                        .putBoolean(Settings.PREF_FIRST_APP_LAUNCH, false)
                        .apply()
                    onGrantedPermission()
                }, {
                    showFolderExplainDialog(
                        isFirst = false, isEmulatorData = false,
                        launchUri = if (lastGameDirUriStr == null) {
                            CitraUtil.getGameDirSAFUri()
                        } else {
                            Uri.parse(lastGameDirUriStr)
                        }
                    )
                }) isOk@{
                    val uriStr = uri.toString()
                    if (lastGameDirUriStr != null) {
                        val sdcardName1 =
                            MarketGamePathUtil.findSDCardNameFromSAFPath(lastGameDirUriStr)
                        val sdcardName2 = MarketGamePathUtil.findSDCardNameFromSAFPath(uriStr)
                        if (!sdcardName1.equals(sdcardName2, true)) {
                            //sd卡名不相同，不通过
                            return@isOk false
                        }
                    }
                    return@isOk uriStr.endsWith(CitraUtil.GAME_DIR_PATH_SHORT, true)
                }
            } ?: showFolderExplainDialog(
                isFirst = true, isEmulatorData = false,
                launchUri = if (lastGameDirUriStr == null) {
                    CitraUtil.getGameDirSAFUri()
                } else {
                    Uri.parse(lastGameDirUriStr)
                }
            )
        }

    private var installZipPath: String? = null
    private var installCiaList: List<String>? = null

    //目标游戏
    private var targetGameId: String? = null
    private var targetGame: Game? = null

    override fun onGrantedPermission() {
        //创建根目录文件夹，后续可以给用户使用SAF选择
        IOUtil.createOrExistsDir(CitraUtil.getEmuRootDirFile())
        //提早写入必要的文件，防止部分手机首次无法读取到密钥等文件
        InitFileUtil.init25Files()
        if (!PermissionsHandler.hasWriteAccess(this)) {
            //没有读写权限
            showFolderExplainDialog(isFirst = true, isEmulatorData = true)
            return
        }
        //优先判断盒子传递的文件夹
        val marketAppPath = marketAppPath
        val gameDirUriStr: String
        val hasGameDirReadAccess: Boolean
        if (marketAppPath != null) {
            val safPair = MarketGamePathUtil.splitFileSDCardAndPathSAF(marketAppPath)
            val sdcardName = safPair.first
            gameDirUriStr = MarketGamePathUtil.getDirPathSAF(
                sdcardName,
                MarketGamePathUtil.getGameDirPath(CitraUtil.PLATFORM_3DS), false
            )
            val gameDirUriStrShort = MarketGamePathUtil.getDirPathSAF(
                sdcardName,
                MarketGamePathUtil.getGameDirPath(CitraUtil.PLATFORM_3DS), true
            )
            //用短的去判断是否有读写权限，因为选完文件夹系统返回的就是短的
            hasGameDirReadAccess = CitraUtil.hasGameDirReadAccess(this, gameDirUriStrShort)
        } else {
            gameDirUriStr = CitraUtil.getGameDirSAFPath(false)
            val gameDirUriStrShort = CitraUtil.getGameDirSAFPath(true)
            hasGameDirReadAccess = CitraUtil.hasGameDirReadAccess(this, gameDirUriStrShort)
        }
        if (!hasGameDirReadAccess) {
            lastGameDirUriStr = gameDirUriStr
            showFolderExplainDialog(
                isFirst = true, isEmulatorData = false,
                launchUri = Uri.parse(gameDirUriStr)
            )
            return
        }
        super.onGrantedPermission()
    }

    /**
     * 显示文件夹说明弹窗
     * @param isFirst 是否第一次选择文件夹
     * @param isEmulatorData true:模拟器数据文件夹。false:游戏文件夹
     */
    private fun showFolderExplainDialog(
        isFirst: Boolean, isEmulatorData: Boolean,
        launchUri: Uri = if (isEmulatorData) {
            CitraUtil.getEmuRootDirSAFUri()
        } else {
            CitraUtil.getGameDirSAFUri()
        }
    ) {
        showFolderExplainDialog(this, isFirst, isEmulatorData, {
            doStartAuthorizationFolder(isEmulatorData, launchUri)
        }, {
            finish()
        }, dirPath = if (isEmulatorData) {
            "主SD卡${CitraUtil.EMU_ROOT_DIR_NAME}"
        } else {
            if (lastGameDirUriStr == null) {
                GAME_DIR_PATH_SHOW
            } else {
                val sdcardName = MarketGamePathUtil.findSDCardNameFromSAFPath(lastGameDirUriStr)
                if (sdcardName != MarketGamePathUtil.SAF_DEFAULT_SDCARD_NAME) {
                    "${sdcardName}/${GAME_DIR_PATH_SHOW}"
                } else {
                    GAME_DIR_PATH_SHOW
                }
            }
        }
        )
    }

    private fun doStartAuthorizationFolder(isEmulatorData: Boolean, launchUri: Uri) {
        try {
            if (isEmulatorData) {
                emulatorDataPicker.launch(launchUri)
            } else {
                gameDirPicker.launch(launchUri)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            showErrorDialog("未找到支持的系统文件管理器，建议联系手机厂商")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        instance = WeakReference(this)
        super.onCreate(savedInstanceState)
    }

    override fun onDestroy() {
        instance?.clear()
        instance = null
        super.onDestroy()
    }

    override fun startGame(romPath: String?, isIntentUri: Boolean) {
        installZipPath = null
        installCiaList = null
        targetGameId = null
        targetGame = null
        if (romPath.isNullOrEmpty()) {
            toastAndFinish("游戏路径为空")
            return
        }
        //先关闭原来的游戏
        NativeLibrary.sEmulationActivity.get()?.finish()
        requestInitData(object : CheatCallback<CheatDataBean>() {
            override fun onSuccess(response: Response<BaseBean<CheatDataBean>>?) {
                response?.body()?.let {
                    if (it.code == 0) {
                        it.data?.let { cheatBean ->
                            //写金手指文件
                            val cheatFilePath =
                                AiwuSimulator.getCheatListener().getCheatFilePath(cheatBean)
                            AiwuSimulator.getCheatListener()
                                .write2CheatFile(cheatFilePath, cheatBean)
                            //写金手指json文件
                            val cheatJsonFilePath =
                                AiwuSimulator.getCheatListener().cheatJsonFilePath
                            val cheatJson = JSON.toJSONString(cheatBean)
                            AiwuSimulator.getCheatListener()
                                .write2CheatJsonFile(cheatJsonFilePath, cheatJson)
                            //不再支持后台配置，因为核心版本迭代，老配置对不上或者没必要
                            if (!cheatBean.romName.isNullOrEmpty()) {
                                checkInstallStatus(romPath, cheatBean.romName)
                                return
                            }
                        }
                    }
                }
                checkInstallStatus(romPath, null)
            }

            override fun onError(response: Response<BaseBean<CheatDataBean>>?) {
                super.onError(response)
                checkInstallStatus(romPath, null)
            }
        })
    }

    /**
     * 检查安装状态 已安装的就直接打开游戏
     * @param romPath 盒子传递的原始路径（.zip）
     * @param gameId 游戏编号
     */
    private fun checkInstallStatus(romPath: String, gameId: String?) {
        lifecycleScope.launch(Dispatchers.Default) {
            runCatching {
                val targetGameId = if (GameIdUtil.is3DSGameId(gameId)) {
                    gameId
                } else {
                    GameIdUtil.getGameId(romPath)
                }
                val romFile = File(romPath)
                if (targetGameId.isNullOrEmpty()) {
                    //没有游戏编号
                    if (!romFile.exists()) {
                        // 可以直接运行的游戏文件
                        val runDirectlyGameFile = findRunDirectlyGameFile(romFile.parentFile)
                        if (runDirectlyGameFile != null) {
                            startByRunDirectlyGameFile(runDirectlyGameFile)
                            return@launch
                        }
                        runOnUiThreadEx {
                            toastAndFinish("游戏ID和游戏文件都不存在,请在爱吾游戏宝盒删除游戏后重新下载")
                        }
                        return@launch
                    }
                }
                this@EntryActivity.targetGameId = targetGameId
                //刷新游戏列表
                val gameList = GameHelper.getGames()
                if (!targetGameId.isNullOrEmpty()) {
                    //有gameId的情况下,检查下是否已经安装
                    val targetGameIdLong = GameIdUtil.convertGameId(targetGameId)
                    gameList.forEach {
                        if (targetGameIdLong == it.titleId) {
                            //找到目标游戏了
                            startGame(it)
                            return@launch
                        }
                    }
                }
                if (!romFile.exists()) {
                    //游戏文件没了
                    runOnUiThreadEx { toastAndFinish("游戏文件不存在,请在爱吾游戏宝盒删除游戏后重新下载") }
                    return@launch
                }
                //开始解压和安装
                runOnUiThreadEx { unzipRom(romPath) }
            }.onFailure {
                it.printStackTrace()
                runOnUiThreadEx { toastAndFinish("启动游戏出错:${it.cause}") }
            }
        }
    }

    /**
     * 解压缩
     */
    private fun unzipRom(romPath: String) {
        lifecycleScope.launch(Dispatchers.Default) {
            runCatching {
                val oldFile = File(romPath)
                if (SDCardUtils.getExternalAvailableSize() < oldFile.length()) {
                    runOnUiThreadEx { toastAndFinish("错误：SD卡储存空间不足,无法解压") }
                    return@launch
                }
                runOnUiThreadEx { showLoadingTip("正在解压中,请勿离开此页面…") }
                runCatching {
                    val filePaths = IOUtil.unzipFiles(
                        romPath,
                        false,
                        false,
                        false
                    ) { zipSize, unzippedCount, progress ->
                        refreshProgress(true, progress)
                    }
                    //处理user.zip
                    val userZips = filePaths.filter {
                        OtherUtil.getFileName(it).equals("user.zip", true)
                    }
                    userZips.forEach {
                        IOUtil.unzipFile(it, CitraUtil.getEmuRootDirFile().absolutePath, true)
                        IOUtil.delete(it)
                        filePaths.remove(it)
                    }
                    //安装rom
                    runOnUiThreadEx { installRom(romPath, filePaths) }
                }
            }.onFailure {
                it.printStackTrace()
                runOnUiThreadEx { toastAndFinish("解压游戏出错:${it.cause}") }
            }
        }
    }

    /**
     * 安装rom
     */
    private fun installRom(zipPath: String, filePaths: List<String>) {
        installZipPath = zipPath
        lifecycleScope.launch(Dispatchers.Default) {
            runCatching {
                val ciaList = arrayListOf<String>()
                val otherList = arrayListOf<String>()
                filePaths.forEach {
                    val extension = OtherUtil.getFileExtension(it).lowercase()
                    if (extension == "cia") {
                        ciaList.add(it)
                    } else if (Game.extensions.contains(extension)) {
                        otherList.add(it)
                    }
                }
                if (ciaList.isEmpty() && otherList.isEmpty()) {
                    //文件有误
                    runOnUiThreadEx { toastAndFinish("安装错误：未找到有效的游戏文件，请联系客服") }
                    return@launch
                }
                if (ciaList.isNotEmpty()) {
                    //加个50MB
                    var installCIASize = 50 * 1024 * 1024L
                    ciaList.forEach {
                        installCIASize += File(it).length()
                    }
                    if (SDCardUtils.getExternalAvailableSize() < installCIASize) {
                        runOnUiThreadEx { toastAndFinish("错误：SD卡储存空间不足,无法安装") }
                        return@launch
                    }
                    installCiaList = ciaList
                    //待安装的cia
                    val installCiaFiles = ciaList.map {
                        CitraUtil.convertGameFilePath2SafUri(File(it)).toString()
                    }.toTypedArray()
                    runOnUiThreadEx {
                        showLoadingTip("安装中,请勿离开此页面…")
                        val workManager = WorkManager.getInstance(applicationContext)
                        workManager.enqueueUniqueWork(
                            "installCiaWork", ExistingWorkPolicy.APPEND_OR_REPLACE,
                            OneTimeWorkRequest.Builder(CiaInstallWorker::class.java)
                                .setInputData(
                                    Data.Builder().putStringArray("CIA_FILES", installCiaFiles)
                                        .build()
                                )
                                .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
                                .build()
                        )
                    }
                } else {
                    //只有免安装的游戏
                    if (targetGameId.isNullOrEmpty() && otherList.size == 1) {
                        val targetUri =
                            CitraUtil.convertGameFilePath2SafUri(File(otherList.first())).toString()
                        targetGameId = GameIdUtil.convertGameId(NativeLibrary.getTitleId(targetUri))
                    }
                    runOnUiThreadEx { onInstallFinished() }
                }
            }.onFailure {
                it.printStackTrace()
                runOnUiThreadEx { toastAndFinish("安装游戏出错:${it.cause}") }
            }
        }
    }

    /**
     * 安装结束，找到目标游戏并启动
     */
    private fun onInstallFinished() {
        if (targetGameId.isNullOrEmpty()) {
            toastAndFinish("错误：没有找到要启动的游戏ID")
            return
        }
        LogUtil.d("安装结束:${targetGameId}")
        lifecycleScope.launch(Dispatchers.Default) {
            runCatching {
                //刷新游戏列表
                val gameList = GameHelper.getGames()
                val targetGameIdLong = GameIdUtil.convertGameId(targetGameId!!)
                gameList.forEach {
                    if (targetGameIdLong == it.titleId) {
                        //取到游戏了
                        GameIdUtil.saveGameId2GameIdCacheFile(
                            File(AiwuSimulator.ROM_PATH),
                            targetGameId!!
                        )
                        if (deleteZip) {
                            //删除zip
                            installZipPath?.let { file ->
                                val fileExtension = OtherUtil.getFileExtension(file)
                                if (fileExtension.equals("cia", ignoreCase = true)
                                    || fileExtension.equals("zip", ignoreCase = true)
                                ) {
                                    IOUtil.delete(file)
                                }
                            }
                        }
                        //删除cia
                        installCiaList?.forEach { file ->
                            IOUtil.delete(file)
                        }
                        startGame(it)
                        return@launch
                    }
                }
                runOnUiThreadEx { toastAndFinish("安装游戏后启动出错:未找到游戏编号\"${targetGameId}\"的游戏") }
            }.onFailure {
                it.printStackTrace()
                runOnUiThreadEx { toastAndFinish("安装游戏后启动出错:${it.cause}") }
            }
        }
    }

    /**
     * 刷新安装cia的进度
     * @param max 总的大小
     * @param progress 已安装的大小
     */
    fun refreshInstallCiaProgress(max: Int, progress: Int) {
        refreshProgress(false, (progress * 100.0 / max).toInt())
    }

    /**
     * 刷新安装cia的状态
     */
    fun refreshInstallCiaStatus(filename: String, status: NativeLibrary.InstallStatus) {
        runOnUiThread {
            val tip = getString(
                when (status) {
                    NativeLibrary.InstallStatus.Success -> {
                        org.citra.citra_emu.R.string.cia_install_success
                    }

                    NativeLibrary.InstallStatus.ErrorAborted -> {
                        org.citra.citra_emu.R.string.cia_install_error_aborted
                    }

                    NativeLibrary.InstallStatus.ErrorInvalid -> {
                        org.citra.citra_emu.R.string.cia_install_error_invalid
                    }

                    NativeLibrary.InstallStatus.ErrorEncrypted -> {
                        org.citra.citra_emu.R.string.cia_install_error_encrypted
                    }

                    else -> {
                        org.citra.citra_emu.R.string.cia_install_error_unknown
                    }
                }, filename
            )
            showLoadingTip(tip)
        }
    }

    /**
     * 安装CIA结束
     */
    fun onInstallCiaFinish(selectedFiles: Array<String>) {
        lifecycleScope.launch(Dispatchers.Default) {
            if (targetGameId.isNullOrEmpty() && selectedFiles.size == 1) {
                targetGameId =
                    GameIdUtil.convertGameId(NativeLibrary.getTitleId(selectedFiles.first()))
            }
            runOnUiThreadEx { onInstallFinished() }
        }
    }

    /**
     * 刷新进度
     * @param isUnzip 是否解压
     * @param progress 百分比进度
     */
    private fun refreshProgress(isUnzip: Boolean, progress: Int) {
        runOnUiThreadEx { showLoadingTip((if (isUnzip) "正在解压中" else "正在安装中") + progress + "%,请勿离开此页面…") }
    }

    /**
     * 找到可以直接运行的游戏文件（除了cia）
     * @param dirFile 文件夹
     */
    private fun findRunDirectlyGameFile(dirFile: File?): File? {
        dirFile ?: return null
        val gameFileList = IOUtil.listFilesInDirWithFilter(dirFile, {
            Game.extensions.contains(OtherUtil.getFileExtension(it))
        }, { file1, file2 ->
            val diff = file2.length() - file1.length()
            when {
                diff > 0 -> {
                    1
                }

                diff < 0 -> {
                    -1
                }

                else -> {
                    0
                }
            }
        })
        return gameFileList.firstOrNull()
    }

    /**
     * 可直接运行的游戏文件开始游戏
     */
    private fun startByRunDirectlyGameFile(gameRomFile: File) {
        val game = GameHelper.getGame(
            CitraUtil.convertGameFilePath2SafUri(gameRomFile),
            isInstalled = false,
            addedToLibrary = false
        )
        startGame(game)
    }

    //真正的开始游戏
    private fun startGame(game: Game) {
        this@EntryActivity.targetGame = game
        runOnUiThreadEx {
            startEntryGameTimer()
        }
    }

    override fun startGameAct() {
        targetGame?.let {
            startActivity(Intent(this@EntryActivity, EmulationActivity::class.java).apply {
                putExtra("game", it)
            })
        }
    }

    override fun resetSettings(): Boolean {
        PrefsHelper.instance.resetSettings()
        val settingsFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_CONFIG)
        if (!settingsFile.delete()) {
            LogUtil.e("删除配置文件失败")
        }
        if (DirectoryInitialization.setCitraUserDirectory()) {
            CitraApplication.documentsTree.setRoot(Uri.parse(DirectoryInitialization.userPath))
            NativeLibrary.createConfigFile()
        }
        SystemSaveGame.apply {
            load()
            setUsername("CITRA")
            setBirthday(3, 25)
            setSystemLanguage(1)
            setSoundOutputMode(1)
            setCountryCode(49)
            setPlayCoins(42)
            save()
        }
        return false
    }

    override fun marketAskDeleteGame(
        gameFilePathUri: Uri?,
        gameDirPathUri: Uri?,
        gameFilePath: String,
        isKeepSaves: Boolean,
        callback: DeleteGameCallback
    ) {
        lifecycleScope.launch(Dispatchers.IO) {
            var deleteResult = DeleteGameCallback.RESULT_FAIL
            runCatching {
                val gameId = GameIdUtil.getGameId(gameFilePath)
                if (gameId.isNullOrEmpty()) {
                    //只处理能拿到romName的情况
                    LogUtil.e("删除失败:未取到游戏编号，$gameFilePath")
                    callback.onDeleteGameFinish(deleteResult)
                    return@launch
                }
                //删除游戏文件夹
                val gameFile = File(gameFilePath)
                //删除游戏文件夹
                val dirFile = getGameDirFile(gameFile)
                IOUtil.delete(dirFile)
                deleteResult = RESULT_SUCCESS_ONLY_GAME_FILE
                val pid = gameId.substring(0, 8).lowercase()
                val subid = gameId.substring(8).lowercase()
                if (pid == "00040010" || pid == "00040030") {
                    val system = CitraUtil.getSystemTitleDirectory()
                    val path = String.format("%s/%s/%s", system, pid, subid)
                    if (!IOUtil.delete(path)) {
                        LogUtil.e(path + "删除失败")
                    }
                } else if (pid == "00040000") {
                    // App
                    val root = CitraUtil.getApplicationDirectory()
                    var path = String.format("%s/%s/%s/content", root, pid, subid)
                    if (!IOUtil.delete(path)) {
                        LogUtil.e(path + "删除失败")
                    }
                    // Updates
                    path = String.format("%s/0004000e/%s/content", root, subid)
                    if (!IOUtil.delete(path)) {
                        LogUtil.e(path + "删除失败")
                    }
                    // DLCs
                    path = String.format("%s/0004008c/%s/content", root, subid)
                    if (!IOUtil.delete(path)) {
                        LogUtil.e(path + "删除失败")
                    }
                } else if (pid == "0004000e" || pid == "0004008c") {
                    // Updates
                    val root: String = CitraUtil.getApplicationDirectory()
                    var path = String.format("%s/0004000e/%s/content", root, subid)
                    if (!IOUtil.delete(path)) {
                        LogUtil.e(path + "删除失败")
                    }
                    // DLCs
                    path = String.format("%s/0004008c/%s/content", root, subid)
                    if (!IOUtil.delete(path)) {
                        LogUtil.e(path + "删除失败")
                    }
                }
                if (!isKeepSaves) {
                    //不保留存档
                    //即时存档
                    val statePattern =
                        Pattern.compile("$gameId(.)*((\\.([0-9]+)\\.cst)|(_([0-9]+)\\.png))")
                    val stateFiles =
                        IOUtil.listFilesInDirWithFilter(CitraUtil.getStateDir()) { pathname ->
                            statePattern.matcher(pathname.getName()).matches()
                        }
                    for (stateFile in stateFiles) {
                        IOUtil.delete(stateFile)
                    }
                    //本体存档
                    if (pid == "00040010" || pid == "00040030") {
                        //系统应用，暂时不处理存档
                        //b.s();
                    } else {
                        val root: String = CitraUtil.getApplicationDirectory()
                        val path = String.format("%s/%s/%s/data", root, pid, subid)
                        if (!IOUtil.delete(path)) {
                            LogUtil.e(path + "删除失败")
                        }
                    }
                    deleteResult = RESULT_SUCCESS_BOTH
                }
            }.onFailure {
                it.printStackTrace()
            }
            callback.onDeleteGameFinish(deleteResult)
        }
    }

    private fun getGameDirFile(extraFile: File): File? {
        return if (extraFile.isDirectory()) {
            extraFile
        } else {
            extraFile.getParentFile()
        }
    }

    override fun unzipRomFile(romPath: String?): Int = UNZIP_NO
}
